package com.hmdp.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.hmdp.dto.UserDTO;
import com.hmdp.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.hmdp.utils.RedisConstants.LOGIN_USER_KEY;


//先执行该拦截器，拦截一切路径
//这个拦截器保证了已经登录的用户如果访问不需要登录的页面也会刷新token有效时间
public class RefressTokenInterceptor implements HandlerInterceptor {

    //该类没有交给ioc容器管理，不能自动注入 通过构造方法让mvc配置类注入
    private StringRedisTemplate stringRedisTemplate;

    public RefressTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    //拦截一切路径用于刷新token时间 不论是否登录都放行到下一个拦截器（登录就保存用户信息）
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求头的token，不是key
        String token = request.getHeader("authorization");
        //判断key是否为空
        if(StrUtil.isBlank(token)){
            //如果为空（前端没传token过来）用户没登录，直接放行到下一个拦截器
            return true;
        }
        //从redis获取token的map集合，判断map集合是否为空
        String key = LOGIN_USER_KEY + token;  //真正的key
        Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key);
        //如果map为空
        if(map.isEmpty()){
            //用户未登陆，不保存到ThreadLocal中,不刷新过期时间，直接放行到下一个拦截器
           return true;
        }

        //执行到这里表示用户已经登录，保存到ThreadLocal中并刷新token有效时间，
        //这个拦截器保证了已经登录的用户如果访问不需要登录的页面也会刷新token有效时间

        //将map集合中的value类型恢复为原来的类型
        //反序列化为原始类型
    /*    map.forEach((key2, value) -> {
            try {
                //反序列化为map集合
                Object originalValue = objectMapper.readValue((String) value, Object.class);  // 反序列化
                map.put(key2, originalValue); //覆盖原来序列化的字符串（value）
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        });*/

        //将map集合转为userdto对象，用map填充bean 注意不是maptobean
        UserDTO userDTO = BeanUtil.fillBeanWithMap(map,new UserDTO(),false);
        //如果存在key和对应的value则 保存用户到ThreadLocal中
        UserHolder.saveUser(userDTO);
        //重新设置有效期30分钟
        stringRedisTemplate.expire(key,30, TimeUnit.MINUTES);
        return true;
    }
}
